﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PSDLib.Models
{
    public class dl_burn
    {
        public string id { get; set; }
        public string device_id { get; set; }
        public string dl_task_id { get; set; }
        public string entry_id { get; set; }
        public string object_id { get; set; }
        public string title { get; set; }
        public int burn_copy { get; set; }
        public int burn_type { get; set; }
        public int burn_mode { get; set; }
        public DateTime? burn_start_time { get; set; }
        public DateTime? burn_end_time { get; set; }
        public int state { get; set; }
        public string error_log { get; set; }
        public int file_count { get; set; }
        public long file_total_size { get; set; }
        public int dvd_count { get; set; }
        public long dvd_size { get; set; }
        public DateTime create_time { get; set; }
    }

    public class dl_burn_dvd
    {
        public string id { get; set; }
        public string dl_task_id { get; set; }
        public string burn_id { get; set; }
        public string dvd_title { get; set; }
        public int dvd_num { get; set; }
        public string dvd_type { get; set; }
        public long dvd_size { get; set; }
        public int file_count { get; set; }
        public long file_total_size { get; set; }
        public DateTime create_time { get; set; }
        public DateTime? burn_start_time { get; set; }
        public DateTime? burn_end_time { get; set; }
        public int burn_percent { get; set; }
        public int state { get; set; }
        public string error_log { get; set; }
    }

    public class dl_burn_files
    {
        public string id { get; set; }
        public string dl_task_id { get; set; }
        public string burn_id { get; set; }
        public string dvd_id { get; set; }
        public string file_id { get; set; }
        public string file_name { get; set; }
        public string file_path { get; set; }
        public long file_size { get; set; }
        public string dvd_file_name { get; set; }
        public string dvd_file_path { get; set; }
        public DateTime create_time { get; set; }
        public int state { get; set; }
    }

    public class BurnTask
    {
        private const double MaxDVDPercent = 0.95;
        /// <summary>
        /// 刻录模式 0：立即刻录，1：同步刻录模式
        /// </summary>
        public dl_burn BurnInfo { get; set; }
        public List<dl_burn_dvd> DVDList { get; set; }
        public List<dl_burn_files> FileList { get; set; }

        public int State { get; set; }

        public delegate void DVDReadyToBurnEventHandler(dl_burn_dvd dvd);
        public event DVDReadyToBurnEventHandler OnDVDReadyToBurn;
        public delegate void AddDVDEventHandler(dl_burn_dvd dvd);
        public event AddDVDEventHandler OnAddDVD;
        public delegate void AddFileEventHandler(dl_burn_files file);
        public event AddFileEventHandler OnAddFile;
        public BurnTask()
        {
            DVDList = new List<dl_burn_dvd>();
            FileList = new List<dl_burn_files>();
        }

        public dl_burn_dvd GetDVD(dl_burn_files file)
        {
            dl_burn_dvd dvd = null;

            var dvdList = DVDList.Where(t => t.state == (int)BurnDVDState.光盘未满).ToList();
            for (int i = 0; i < dvdList.Count; i++)
            {
                if ((dvdList[i].file_total_size + file.file_size) <= dvdList[i].dvd_size * MaxDVDPercent)
                {
                    dvd = dvdList[i];
                    break;
                }
                else
                {
                    DVDReady(dvd);
                }
            }

            if (dvd == null)
            {
                dvd = new dl_burn_dvd();
                dvd.id = Guid.NewGuid().ToString();
                dvd.dl_task_id = BurnInfo.dl_task_id;
                dvd.burn_id = BurnInfo.id;
                dvd.dvd_size = BurnInfo.dvd_size;
                dvd.dvd_num = DVDList.Count + 1;
                dvd.dvd_title = BurnInfo.title + "-" + dvd.dvd_num;
                dvd.file_count = 0;
                dvd.file_total_size = 0;
                dvd.create_time = DateTime.Now;
                dvd.burn_percent = 0;
                dvd.state = (int)BurnDVDState.光盘未满;
                DVDList.Add(dvd);

                this.BurnInfo.dvd_count += 1;

                OnAddDVD?.Invoke(dvd);
            }

            return dvd;
        }

        public void DVDReady(dl_burn_dvd dvd)
        {
            if (dvd != null)
            {
                dvd.state = (int)BurnDVDState.等待刻录;

                OnDVDReadyToBurn?.Invoke(dvd);
            }
        }

        public void BurnReady()
        {
            var dvdList = DVDList.Where(t => t.state == (int)BurnDVDState.光盘未满).ToList();
            for (int i = 0; i < dvdList.Count; i++)
            {
                DVDReady(dvdList[i]);
            }
        }

        public void AddFile(dl_burn_files file)
        {
            var dvd = GetDVD(file);

            if (dvd != null)
            {
                file.dvd_id = dvd.id;
                dvd.file_count += 1;
                dvd.file_total_size += file.file_size;
                FileList.Add(file);

                OnAddFile?.Invoke(file);
            }
        }
    }

    public class BurnTaskList : List<BurnTask>
    {

    }

    public enum BurnDVDState : int
    {
        光盘未满 = -2,
        等待刻录 = -1,
        正在刻录 = 0,
        刻录完成 = 1,
        刻录失败 = 2,
        刻录取消 = 3,
    }

    public enum BurnMode : int
    {
        ImmediateBurn = 0,
        SyncBurn = 1,
    }
}
